﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Messaging;
using MessageCallAspect.Inspector.Attributes;
using MessageCallAspect.Aspect.Cache;

namespace MessageCallAspect.Aspect.Cache
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public sealed class CacheAspectAttribute : MessageSinkAttribute
    {
        public double TimeoutMinute { get; set; }
        private readonly Type m_CachePolicyObjectType;

        public CacheAspectAttribute()
            : this(null)
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cachePolicyObjectType">should be type of ICachePolicy</param>
        public CacheAspectAttribute(Type cachePolicyObjectType)
        {
            if (cachePolicyObjectType != null
                && !cachePolicyObjectType.GetInterfaces().Contains(typeof(ICachePolicy)))
            {
                throw new InvalidCastException("CachePolicyObjectType should type of ICachePolicy");
            }
            m_CachePolicyObjectType = cachePolicyObjectType;
            Order = int.MaxValue;
        }

        public override IMessageSink CreateMessageSink(IServiceProvider context, object target, IMessageSink nextSink)
        {
            ICachePolicy m_CachePolicy = null;
            if (m_CachePolicyObjectType != null)
            {
                m_CachePolicy = Activator.CreateInstance(m_CachePolicyObjectType) as ICachePolicy;
            }
            CacheMessageSink cacheMessageSink = new CacheMessageSink(target, nextSink, context, m_CachePolicy);
            if (TimeoutMinute != 0)
            {
                cacheMessageSink.Timeout = TimeSpan.FromMinutes(TimeoutMinute);
            }
            return cacheMessageSink;

        }
    }
}
